{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import mean_squared_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 加载原始数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 211,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "pkl_file = open('datas/linear_data.pkl', 'rb')\n",
    "X_train, X_test, y_train, y_test = pickle.load(pkl_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 212,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(80, 1)"
      ]
     },
     "execution_count": 212,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 213,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x2052ca9390>]"
      ]
     },
     "execution_count": 213,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 基础线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 214,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Regression(object):\n",
    "    \n",
    "    \"\"\"\n",
    "        基础线性回归模型，使用输入的X和y进行参数回归\n",
    "        超参：\n",
    "        n_iterations:int 训练的步数，迭代多少次\n",
    "        learning_rate:float 学习率\n",
    "        \n",
    "        内部函数:\n",
    "        initialize_weights:初始化参数\n",
    "        fit:开始训练\n",
    "        predict:预测\n",
    "        \n",
    "        内部的数据:\n",
    "        n_iterations\n",
    "        learning_rate\n",
    "        regularization:正则化参数\n",
    "        regularization.grad:正则化的梯度函数\n",
    "    \"\"\"\n",
    "    \n",
    "    def __init__(self, n_iterations, learning_rate):\n",
    "        self.n_iterations=n_iterations\n",
    "        self.learning_rate=learning_rate\n",
    "        self.regularization=lambda x:0\n",
    "        self.regularization.grad=lambda x:0\n",
    "    \n",
    "    def initialize_weights(self, n_features):\n",
    "        \"\"\"初始化系数，输入是feature的个数，输出是一个随机初始化好的参数矩阵,[-1/sqrt(N),1/sqrt(N)]\"\"\"\n",
    "        # 实验得出经典算法，随机分布初始化系数\n",
    "        limit=1/math.sqrt(n_features)\n",
    "        self.w=np.random.uniform(-limit,limit,(n_features,))\n",
    "        #Uniform Distribution/Xavier/MSRA/Gaussian 高斯初始化\n",
    "    \n",
    "    def fit(self, X, y):\n",
    "        #插入偏置列1到X中\n",
    "        X = np.insert(X,0,1,axis=1)#给每一行的第0列增加一个1\n",
    "        self.training_errors = []#保存每一次步长的训练Loss\n",
    "        self.initialize_weights(n_features=X.shape[1])#初始化参数w\n",
    "        \n",
    "        #进行梯度下降迭代\n",
    "        for i in range(self.n_iterations):\n",
    "            y_pred=X.dot(self.w)#进行预测\n",
    "            #计算Loss\n",
    "            mse=np.mean(0.5*(y-y_pred)**2+self.regularization(self.w))\n",
    "            self.training_errors.append(mse)#将Loss加入到training_errors的数组中\n",
    "            #计算带有正则化项的梯度\n",
    "            g_w=-(y-y_pred).T.dot(X)/len(X)+self.regularization.grad(self.w)\n",
    "            #根据梯度下降的算法更新参数\n",
    "            self.w-=self.learning_rate*g_w\n",
    "            \n",
    "    def predict(self,X):\n",
    "        #通过输入X预测一个样本\n",
    "        X=np.insert(X,0,1,axis=1)\n",
    "        pred=X.dot(self.w)\n",
    "        return pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 215,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_and_draw(model):\n",
    "    y_pred=model.predict(X_test)\n",
    "    #print(y_pred.shape)\n",
    "    mse=mean_squared_error(y_test,y_pred)\n",
    "    print(\"方差:\",mse)\n",
    "    plt.plot(X_test,y_test,'k.')\n",
    "    plt.plot(X_test,y_pred,'Y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 216,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l1_regularization():\n",
    "    \"\"\"L1正则化类/函数\n",
    "    参数:\n",
    "    \n",
    "    alpha--L1正则化系数\n",
    "    \"\"\"\n",
    "    def __init__(self, alpha):\n",
    "        self.alpha=alpha\n",
    "    def __call__(self,w):\n",
    "        return self.alpha*np.linalg.norm(w,ord=1)\n",
    "    def grad(self,w):\n",
    "        #w>0->w`=1;w<0->w`=0;w==0->w`=0\n",
    "        return self.alpha*np.sign(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 217,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l2_regularization():\n",
    "    \"\"\"L2正则化参数\n",
    "    参数：\n",
    "    \n",
    "    alpha 正则化系数\n",
    "    \"\"\"\n",
    "    def __init__(self,alpha):\n",
    "        self.alpha=alpha\n",
    "    \n",
    "    def __call__(self,w):\n",
    "        return self.alpha*0.5*w.T.dot(w)\n",
    "    \n",
    "    def grad(self,w):\n",
    "        return self.alpha*w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 218,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l1_l2_regularization():\n",
    "    \"\"\"使用在ElasticNet中的正则化\"\"\"\n",
    "    \n",
    "    def __init__(self,alpha,l1_ratio=0.5):\n",
    "        self.alpha=alpha\n",
    "        self.l1_ratio=l1_ratio\n",
    "    \n",
    "    def __call__(self,w):\n",
    "        l1_loss=self.l1_ratio*np.linalg.norm(w,ord=1)\n",
    "        l2_loss=(1-self.l1_ratio)*0.5*w.T.dot(w) #np.linalg.norm(w,ord=2)**2\n",
    "        return self.alpha*(l1_loss+l2_loss)\n",
    "    def grad(self,w):\n",
    "        l1_grad=self.l1_ratio*np.sign(w)\n",
    "        l2_grad=(1-self.l1_ratio)*w\n",
    "        return self.alpha*(l1_grad+l2_grad)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造多项式特征\n",
    "一阶多项式:x,y,z,x2,x3,x4....\n",
    "\n",
    "二阶多项式:x1^2,x2^2,x3^2,x1x2,x1x3,x2x3\n",
    "\n",
    "三阶多项式:x1^3,x1x1x2,x1x2x3....\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "metadata": {},
   "outputs": [],
   "source": [
    "from itertools import combinations_with_replacement\n",
    "\n",
    "def polynomial_features(X, degree):\n",
    "    n_samples, n_features=np.shape(X) #行数、列数\n",
    "    \n",
    "    #对于每一行的Feature构造排列组合，根据排列组合进行特征的乘积，形成新的X`\n",
    "    def index_combinations():\n",
    "        combs=[combinations_with_replacement(range(n_features),i) for i in range(0,degree+1)]\n",
    "        new_combs=[item for sub in combs for item in sub]\n",
    "        return new_combs\n",
    "#     print(\"Feature 列的排列组合:->\", [x for x in index_combinations()])\n",
    "    \n",
    "    comb=index_combinations()\n",
    "    feature_length=len(comb)\n",
    "    output=np.empty((n_samples, feature_length))\n",
    "    print(output.shape) \n",
    "    for i,index_combs in enumerate(comb):\n",
    "        output[:,i]=np.prod(X[:, index_combs], axis=1)\n",
    "    return output "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 220,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 3)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[1., 1., 2.]])"
      ]
     },
     "execution_count": 220,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "polynomial_features(np.array([[1,2]]),degree=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 6)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  1.,  2.,  1.,  2.,  4.],\n",
       "       [ 1.,  4.,  5., 16., 20., 25.]])"
      ]
     },
     "execution_count": 221,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "polynomial_features(np.array([[1,2],[4,5]]),degree=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 222,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 10)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[  1.,   1.,   2.,   1.,   2.,   4.,   1.,   2.,   4.,   8.],\n",
       "       [  1.,   4.,   5.,  16.,  20.,  25.,  64.,  80., 100., 125.]])"
      ]
     },
     "execution_count": 222,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "polynomial_features(np.array([[1,2],[4,5]]),degree=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 223,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(0, 0, 0)\n",
      "(0, 0, 1)\n",
      "(0, 1, 1)\n",
      "(1, 1, 1)\n"
     ]
    }
   ],
   "source": [
    "for x in combinations_with_replacement([0,1],3):print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc-hr-collapsed": false
   },
   "source": [
    "## 多项式回归\n",
    "\n",
    "多个特征的数据不实用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 224,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PolyRegression(Regression):\n",
    "    \"\"\"多项式回归就是将原来的feature转化成多阶的新feature，之后进行线性回归:\n",
    "    \n",
    "    ------------------------------------------\n",
    "    degree:最大的阶数\n",
    "    n_iterations:float\n",
    "    learning_rate:float\n",
    "    \n",
    "    \"\"\"\n",
    "    def __init__(self,degree,n_iterations=3000,learning_rate=0.01):\n",
    "        self.degree=degree\n",
    "        self.regularization=lambda x:0\n",
    "        self.regularization.grad=lambda x:0\n",
    "        super(PolyRegression,self).__init__(n_iterations=n_iterations,learning_rate=learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        X=polynomial_features(X, degree=self.degree)\n",
    "        super(PolyRegression,self).fit(X,y)\n",
    "        \n",
    "    def predict(self,X):\n",
    "        X=polynomial_features(X, degree=self.degree)\n",
    "        return super(PolyRegression,self).predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 225,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=PolyRegression(degree=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 226,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(80, 4)\n"
     ]
    }
   ],
   "source": [
    "model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 227,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20, 4)\n",
      "方差: 295.017150962139\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据的Normalize变换(归一化操作)\n",
    "\n",
    "行归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 228,
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalize(X,axis=-1,order=2):\n",
    "    \"将数据集的每一行进行列的归一化--每一行的向量的L2范数归一\"\n",
    "    L2=np.linalg.norm(X, order, axis)\n",
    "    L2[L2==0]=1 #为了滤掉为0的L2距离，在归一化的时候会出现除零问题\n",
    "    return X/np.expand_dims(L2, axis) #每一行除下去"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 229,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.23606798, 5.        ])"
      ]
     },
     "execution_count": 229,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.linalg.norm([[1, 2],[3, 4]], ord=2, axis=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 230,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2.23606798],\n",
       "       [5.        ]])"
      ]
     },
     "execution_count": 230,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.expand_dims([2.23606798, 5], axis=-1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 231,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.4472136 , 0.89442719],\n",
       "       [0.6       , 0.8       ]])"
      ]
     },
     "execution_count": 231,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "normalize([[1,2],[3,4]],order=2, axis=-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有多项式的Lasso 回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LassoRegression(Regression):\n",
    "    \"\"\"带有L1范数的Lasso多项式回归\n",
    "    ---------------------------\n",
    "    degree:多项式的最高阶\n",
    "    alpha:L1的系数\n",
    "    \n",
    "    n_iteration:float\n",
    "    learning_rate:int\n",
    "    normailzed:bool\n",
    "    \"\"\"\n",
    "    \n",
    "    def __init__(self,degree,alpha,n_iterations=3000,learning_rate=0.01,normalized=True):\n",
    "        self.degree=degree\n",
    "        self.regularization=l1_regularization(alpha=alpha)\n",
    "        self.normalized=normalized\n",
    "        super(LassoRegression, self).__init__(n_iterations,learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        super(LassoRegression, self).fit(X,y)\n",
    "\n",
    "    def predict(self,X):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        return super(LassoRegression, self).predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=LassoRegression(degree=5, alpha=1000, n_iterations=2000, learning_rate=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 234,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(80, 6)\n"
     ]
    }
   ],
   "source": [
    "model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 235,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ -30.94113584,   22.95244389,   96.53289275,   47.37363858,\n",
       "       -104.96433332,   24.41214081,  186.90986761])"
      ]
     },
     "execution_count": 235,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20, 6)\n",
      "方差: 383.75734262403637\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYEAAAD4CAYAAAAKA1qZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3de3zcdZ3v8dcnl0l6T9K0TZo0bdK0aQu0lAY0yGqWcnE9e0Q9q+IFYUGLAouuu6wF9nBw0S2iLgdFWQrLCugK6NGF3UWBRiMIw9qC9JakSZqmbdJb2lx6SzPJ5Hv+yLQEmqRJMzO/ubyfj0cfmfnN7fObab7v/L7f73x/5pxDRESSU4rXBYiIiHcUAiIiSUwhICKSxBQCIiJJTCEgIpLE0rwuYDRyc3PdvHnzvC5DRCSuvPHGGwedczNGuk9chMC8efPYsGGD12WIiMQVM9t5pvuoO0hEJIkpBEREkphCQEQkiSkERESSmEJARCSJKQRERJKYQkBEJAb4/X7WrFmD3++P6uvGxfcEREQSmd/vZ+XKlQQCAXw+H1VVVVRUVETltXUkICLiserqagKBAMFgkEAgQHV1NSdO7KSp6Q62b18d0ddWCIiIeKyyshKfz0daWgrvfW8q73vf87z+egm7dn2Lnp7dRPLkX+oOEhHx2IUXLuGFF77AsWM/JjOzndTUBubMuYP8/FVkZs6J6GsrBEREPHLixC5aWh5g795HCAaPMGvWJcyefTMzZnyMlBRfVGpQCIiIRNmRI2+ye/d3OHDgGQBmzvwkc+Z8lSlTVkS9lrCEgJk9Bvw5cMA5d25oWw7wNDAPaAY+4ZzrMDMDHgA+BBwHrnPOvRmOOkREYlln5+9obr6Hzs4qUlOnUFj4ZQoLv0xmZtGQ9/f7/VRXV1NZWRmx2ULhOhL4EfAg8MSgbauBKufcvWa2OnT9a8CfAQtC/94DPBT6KSKScJxzdHb+hubmf6Cr62V8vjxKSu5j9uxVpKVNG/Zx0Zo2GpbZQc65l4H2d22+Cng8dPlx4CODtj/hBrwOZJlZfjjqEBGJFc452ttf4I9/vISNGy+ju7uR0tLv8Z73NFFUdNuIAQBDTxuNhEiOCcxyzu0NXd4HzApdLgB2D7pfS2jb3kHbMLNVwCqAoqKhD5VERGJRd/d26ur+kq6uV8jImMOCBT8kL+8vSU3NHPVznJw2evJIoLKyMiK1RmVg2DnnzGxME12dc2uBtQDl5eWRmyQrIhImzjn27XuMhoYvk5KSzoIFD5Gff/1ZzfSpqKigqqoqbsYEhrLfzPKdc3tD3T0HQttbgcETXwtD20RE4lYg0EZ9/SoOHvx3srIuZdGiHw05x38sg70VFRURXz4ikiHwHHAtcG/o57ODtt9iZk8xMCDcNajbSEQk7hw69Dx1ddfT19fB/PnfpbDwK5idPuTq5RpBwwnLwLCZ/RTwA2Vm1mJmNzDQ+F9uZg3AZaHrAM8DTUAj8AhwUzhqEBGJtmDwOPX1N7N58//A55vJihXrmTPnq0MGAERvsHcswnIk4Jz71DA3rRzivg64ORyvKyLilcOHN1Bb+1m6u7dRWPhViou/ecaB32gN9o6FvjEsIjIGzgXZtetempvvJj19FsuWrSM7+7S/d4cUrcHesVAIiIiMUnf3Dmprr+Hw4VeZMeOTLFz4EOnp2WN6jmgM9o6FQkBE5AwGpn7+iMbGW4EUFi/+MTNnfpqBVXDim0JARGQEgcBB6utv5ODBXzBt2gdYvPhxMjPnel1W2CgERESG0d7+AnV119Hbe4iSkvtCM39SvS4rrBQCIiLvEgx209T0d7S2PsjEiedw3nm/YsqU870uKyIUAiIigxw58ia1tZ/l+PFaCgq+TEnJGlJTJ3hdVsQoBEREODn189s0N99FevoMli59kZycy70uK+IUAiKS9Lq7m6mr+xxdXa8wY8ZfsHDhw6Sn53hdVlQoBEQkaTnn2L//SRoabgFg0aLHmTXrmoSY+jlaCgERSUq9ve3U13+RtrafMW3aJSxa9CQTJszzuqyoUwiISNJpb38pNPWzjeLiNRQV3ZZwUz9HSyEgIkljYOrn7bS2PsDEiYs577z/YMqUC7wuKyonlB+OQkBEksKRI29RW/sZjh+voaDgrygp+VZMTP30+hwDYTmfgIhIrBqY+nkfb755EX197Sxd+msWLPheTAQAeH+OAR0JiEjCOnFiJ7W119LV9Ttycz/GwoUP4/Plel3WO3h9jgGFgIgkHOccBw78G/X1NwH9lJU9Rl7edTE59dPrcwwoBEQkofT2dlBf/yXa2p5m6tSLWbz4SSZMKPG6rBF5eY4BhYCIJIyOjt9QV3ctgcA+iou/wZw5XyMlRc3cSPTuiEjcCwZPsGPHHbS03M+ECWUsX+5n6tRyr8uKCwoBEYlrR49uorb2Mxw7toXZs29i/vxvk5o60euy4oZCQETiknP9tLTcT1PTHaSlZXPeef/F9Okf8rqsuKMQEJG4c+LEburqrqWz87dMn34VZWWP4PPN8LqsuKQQEJG4sn//UzQ0fIn+/l7Kyh4lL+/6mJz6GS8UAiISF3p7O2louJkDB/6NqVPfy6JFTzJxYqnXZcU9hYCIxLyOjt9SV3ctPT17mDfv6xQV3aGpn2Gid1FEYlZ/fw87dvw9u3d/lwkTSrnggteYOvUir8tKKAoBEYlJr776Yzo7b2PSpH3k599Iael3SU2d5HVZCUeriIpITHGun1de+QrHjl1DILCPu+/20d5+rQIgQhQCIhIzenpa2bTpSoLBB3jjDbjhBvj974NRX145mSgERBKc3+9nzZo1+P3+mH7dAwd+zvr159HV9RppaX/HPfdkcvhwqifLK4eDV+/7WGlMQCSBeXXWqrG8bl/fYRoa/or9+59gypQLWbz4x0ycuJCqqo94trzyeHl9trCxiPiRgJk1m9lmM3vLzDaEtuWY2Utm1hD6mR3pOkSSkVdnrRrt63Z2vsKGDcvYv//HzJ17F8uXv8rEiQuBgeWVb7/99phtPEfi9dnCxiJa3UF/6pw73zl3clm/1UCVc24BUBW6LiJhdvKsVamp0e1WOdPr9vcHaGq6k7feqgRSWL789xQXf52UlPSo1BdpXr3vZ8Occ5F9AbNmoNw5d3DQtm1ApXNur5nlA9XOubLhnqO8vNxt2LAhonWKJCq/3+9Jt8pwr3vsWB21tZ/h6NE3ycu7ntLS/0ta2pSo1RUtXr3vg5nZG4P++B76PlEIgR1AB+CAh51za82s0zmXFbrdgI6T1wc9bhWwCqCoqGjFzp07I1qniESWc449ex5i+/a/JSVlImVljzBjxke9LiuhjSYEojEwfIlzrtXMZgIvmVnd4Budc87MTksi59xaYC0MHAlEoU4RiZCenn1s23Y97e2/Ijv7ShYt+lcyMvK9LkuIQgg451pDPw+Y2S+Bi4D9ZpY/qDvoQKTrEBFvHDz4LNu2fZ5g8Cilpd+noOBmrfoZQyI6MGxmk8xsysnLwBXAFuA54NrQ3a4Fno1kHSISfX19R9i27Qts2fIRMjLmsGLFmxQW3qIAiDGRPhKYBfwy9KGnAf/mnPu1ma0HnjGzG4CdwCciXIeIRIlzjra2/0dj41cIBPZQVLSaefO+TkqKz+vSZAgRDQHnXBOwbIjth4CVkXxtEYm+7u7tNDTcQnv7r5k0aRnnnPNzpk17r9dlyQj0jWERGbf+/h527bqPXbv+EbM05s+/n4KCW7TmfxzQJyQi49Levo6Ghpvo7m5gxoyPU1p6PxkZBV6XJaOkEBCRs/Laa8+xZ8//Jjd3E5mZ81m69Nfk5FzpdVkyRlpFVETGpL8/wCuv3EJn51VMnbqJn/wkjf7+RxUAcUpHAiIyau3tL9DQcCvBYD0bN8KDD8K+ff2UlPi5+OJKr8uTs6AjARE5o+7uJjZv/gibNn0Q6Ke19RbuuAP27IH+/n6mT5/udYlylhQCIjKsYPA4O3bcxR/+sISOjnUUF6/hwgu3sGvXbFJSBpqPlJQUDh065HGlcrbUHSQipzn5ha/t2/+Gnp5dzJz5KebP//apWT+VlZVkZGScOmlKLC+VLCNTCIjIOxw7tpWGhlvp7PwNkyYtZfHiJ8nKev877lNRUUFVVZXnSyXL+CkERAQYOM1jc/PdtLR8j7S0qSxY8CD5+TcO+4WviooKNf4JQCEgkuQGun5+RmPjXxMI7CU//wsUF38Tny/X69IkCjQwLJLEjh9vZNOmD1JT80l8vlmkpz/CL34xjzfeaPC6NIkSHQmIJKFg8AS7d3+LnTvXkJLio7T0AXbtWs7ll195arC3qqpK3T1JQEcCIkmms/MVNmxYRnPz3eTmfoSLLqqjsPBWfve73xMIBAgGgwQCAaqrq70uVaJARwIiSaKv7zBNTbezZ88Pycycx9KlL5CTc8Wp2ysrK/H5fJr2mWQUAiJJ4NCh56mv/yI9PS0UFn6FefPuIS1t8jvuo2mfyUkhIJLAens7aWz8K/bv/zETJy5h+fJXmTZt+MZd0z6Tj0JAJEEdPvzf1NRcTU9PC3Pn3sXcuXeQkpLhdVkSYxQCIgnGuX5aWu6nqWk1Pl8By5f/nqlT3+N1WRKjFAIiCSQQOEhd3XW0t/8Xubkfo6zsUdLTs70uS2KYQkAkQXR2vkJNzafo7W2jtPT7FBTcjJl5XZbEOIWASJxzLsiuXfeyY8ddTJhQwnnn+Zky5QKvy5I4oRAQiWOBwH5qaz9LR8c6Zs68moULHyYtbarXZUkcUQiIxKmOjipqaj5DMNjFwoWPkJ9/w6i7f/x+v74PIIBCQCTu9Pf3sXPnP7Bz5zeYOHERy5atY/Lkc0f9eL/fz8qVK7VGkABaO0gkrvT0tLJx40p27ryHvLzrWLFi/ZgCAKC6ulprBMkpOhIQiROHDj1Pbe3n6O8/waJFT5CXd81ZPY/WCJLBFAIiMa6/v5cdO+5k9+5vM2nSUs455xkmTiw76+fTGkEymEJAJIZ1dzdTW/spDh9+ndmzv8T8+d8lNXXCuJ9XawTJSQoBkRjV1vZLtm27Huf6WbLkGWbO/LjXJUkCUgiIxJj+/h62b7+N1tbvM2VKOUuWPM2ECSVelyUJSiEgcgbRnFN//HgjNTWf5OjRNyks/AolJfdq5U+JKM9CwMw+CDwApAKPOufu9aoWkeFEc079/v1PUV+/CrM0zj33WXJzPxyR1wkHfdkscXgSAmaWCvwAuBxoAdab2XPOuRov6hEZzlBz6sPd6AWD3TQ2foW9e9cyderFLFnyUzIzi8L6GuGkL5slFq++LHYR0Oica3LOBYCngKs8qkVkWCfn1KempkZkTv2xY7W8+eZF7N27lqKi1Zx/fnVMBwDoy2aJxqvuoAJg96DrLcA7znphZquAVQBFRbH9SyGJK5Jz6vfte5z6+ptITZ3E0qW/JifnyrA9dyTpy2aJJWYHhp1za4G1AOXl5c7jciSJhXtOfV/fURoabmL//ifJyqpk8eKfkJExO2zPH2n6slli8SoEWoE5g64XhraJJLSjRzexdesn6O6uZ968u5k79+8ZGCKLL/qyWeLwKgTWAwvMrJiBxv9q4NMe1SIScc459u5dS0PDl0lPz2HZsiqys//U67JEvAkB51yfmd0CvMDAFNHHnHNbvahFJNL6+rrYtm0VbW3PkJ19JYsXP4HPN9PrskQAD8cEnHPPA8979foi0XD48AZqaj7JiRM7KSm5lzlzbsNMK7hL7IjZgWGReOaco7X1e2zffhs+Xx7Ll7/MtGkXe12WyGkUAiJh1tvbTl3d9Rw69CzTp/9PFi36V9LTp3tdlsiQFAIiYdTV5aem5moCgb3Mn38/hYVfHvV5f0W8oBAQCQPn+tm9+9s0Nd1JZuZcli9/jalTy70uS+SMFAIi4xQIHKC29nN0dLzAjBkfp6zsEdLSpnldlsioKARExqGz83fU1HyK3t52Fix4iNmzb1T3j8QVhYDIWXAuyM6d36S5+etMmFDK0qW/YvLkZV6XJTJmCgHxTLyuSd/Ts5fa2s/Q2flbZs36LAsWPERa2mSvyxI5KwoB8US8rknf3v4itbWfJRg8RlnZv5KXd626fySu6auL4ol4W5O+v7+PpqY72LTpSny+WaxYsZ78/OsUABL3dCQgnoinNemPH2+gru4vOXz4VfLzP09p6QOkpk70uiyRsFAIiCdifU165/o5enQTbW1Ps3v3P5GSksnixT9h1iwtdiuJRSEgnom1Nel7evbQ0fES7e0v0tGxjt7eAwDMnPlp5s//DhkZ+R5XKBJ+CgFJWsHgcbq6Xgk1+i9y7NgWANLTZ5CdfQU5OZfT1JTNs89upbKymYoKhYAkHoWAJI2TXTwdHS/R0fEinZ2v4FwPZj6mTfsTSkquITv7CiZPXopZCn6/n8sui78ZTCJjoRCQhNbTs3dQF89Lp7p4Jk06l4KCm8nOvpysrPcPOdA71AwmhYAkGoWAJJRgsPtdXTybgZNdPJeTk3MF2dmXkZFRcMbniqcZTCJnSyEgcc05x7Fjm041+qd38dwb6uJZNuYzesX6DCaRcFAISNwZ6OJZR0fHi7S3v0Rv734AJk48h4KCm8jOvmLYLp6xirUZTCLhphCQmDdyF89lp2byjKaLR0TeSSEgMWegi2fzoC6elwd18Vwyri4eEXknhYDEhJ6efaGpmwP/AoF9wMkuni8N6uKZ5HGlIolFISCeGPii1quhfv0XOXZsEwDp6blkZ1+uLh6RKFEISFT09/dy5Mh6Ojqq6Oio4vBhP84FQl0876O4eA05OVcwefL56uIRiSKFgESEc/0cO7b5VKPf1fUyweBRwJg8+XwKC28lK+tSdfGIeEwhIGHhnKO7u5HOzt/Q0VFFZ+dv6e09CMCECQuZNesasrNXkpVVSXr6dI+rFZGTFAJy1gZW3aw61fD39OwGwOcrICfnQ6FG/1IyMws9rlREhqMQkFHr7W2ns7P6VMN//HgdAGlpOWRnX0pW1u1kZ69kwoQFOuOWSJxQCMiInOuntfUH7Nv3I44e/SPgSEmZRFbW+8nP/zxZWZdqvr5IHFMIyLBOnNhJXd11dHZWM2XKe5g3726ysi5l6tSLSEnxeV2eiISBQkBO45xj//4naGi4FeinrOwx8vJ0UnWRRKQQSDJ+v3/EVTEDgTbq62/k4MFfMm3an7Bo0eNMmFDsQaUiEg0RCwEzuxv4AtAW2nSHc+750G23AzcAQeBW59wLkapD3ub3+1m5cvgzZR08+J9s2/Z5+vo6KCm5jzlzvopZqocVi0ikRfpI4H7n3HcGbzCzJcDVwDnAbGCdmS10zgUjXEvSG+5MWX19R9i+/avs3fsokyYtZdmyF5k8eanX5YpIFHjRHXQV8JRzrgfYYWaNwEWA34NakspQZ8rq6nqV2trPceLEDubM+RrFxV8nJSXD61JFJEoiHQK3mNnngA3A3zjnOoAC4PVB92kJbXsHM1sFrAIoKiqKcJnJYfCZsj7wgfcxa9Zz/PGP95GZOZfzz3+ZrKxLvC5RRKJsXCFgZuuAvCFuuhN4CLgHcKGf3wWuH+1zO+fWAmsBysvL3XjqlLdVVFRw3nlTqK39LLt2bSQv7wZKS+8nLW2K16WJiAfGFQLOuctGcz8zewT4z9DVVmDOoJsLQ9skwpxztLTcT1PT7aSlZXHuuc+Sm/thr8sSEQ9F7GueZpY/6OpHgS2hy88BV5tZhpkVAwuAP0SqDhngnGP79r9l+/a/ISfnz7jwwi0KABGJ6JjAfWZ2PgPdQc3AjQDOua1m9gxQA/QBN2tmUGSdDICWln+ioOAWSku/py9+iQgQwRBwzl0zwm3fBL4ZqdeWtykARGQkWvUrgSkARORMFAIJaiAAblMAiMiIFAIJ6O0A+K4CQERGpBBIMIMDYPbsmxUAIjIihUACeXcALFjw/bAEgN/vZ82aNfj9WtlDJNFoKekEEckAGGnlURGJbzoSSADOOZqa/i7sAQBDrzwqIolDIRDnTgbA7t3fYfbsm8IaAPD2yqOpqamnVh4VkcSh7qA4dnoAPBj2QeDBK48OdzYyEYlfCoE4FY0AOKmiokKNv0iCUndQHBoIgK9FJQBEJLEpBOLM2wHwbQWAiIybQiCOvDMAvqQAEJFxUwjEidMD4AcKABEZN4VAHBgIgNUKABEJO4VAjHs7AO5TAIhI2CkEYtjpAaAxABEJL4VAjBo6APRxiUh4qVWJQQMBcLsCQEQiTi1LjHk7AL6lABCRiFPrEkPeGQBfVACISMSphYkRpwfADxQAIhJxamVigHOOHTvuUACISNSppfHYyQDYteteBYCIRJ1aGw8NDoD8/BsVACISdWpxPPLuAFi48IcKABGJOrU6HhgIgDsVACLiObU8UfZ2AKxRAIiI59T6jIHf72fNmjX4/f6zerwCQERijc4xPEp+v5+VK1cSCATw+XxUVVWN6by77wyAVQoAEYkJaoVGqbq6mkAgQDAYJBAIUF1dPerHDgTA3w8KgIcUACISE9QSjVJlZSU+n4/U1FR8Ph+VlZWjetzbAfCPCgARiTnjao3M7ONmttXM+s2s/F233W5mjWa2zcyuHLT9g6FtjWa2ejyvH00VFRVUVVVxzz33jLorSAEgIrFuvGMCW4CPAQ8P3mhmS4CrgXOA2cA6M1sYuvkHwOVAC7DezJ5zztWMs46oqKioGPU4wDsD4AsKABGJSeMKAedcLTDU2a6uAp5yzvUAO8ysEbgodFujc64p9LinQveNixAYrYEA+N+DAuCfFQAiEpMi1TIVALsHXW8JbRtu+2nMbJWZbTCzDW1tbREqM/zeDoBvKgBEJOad8UjAzNYBeUPcdKdz7tnwlzTAObcWWAtQXl7uIvU64aQAEJF4c8YQcM5ddhbP2wrMGXS9MLSNEbbHNQWAiMSjSLVSzwFXm1mGmRUDC4A/AOuBBWZWbGY+BgaPn4tQDVHjnKO5+a5QAHxeASAicWNcA8Nm9lHg+8AM4L/M7C3n3JXOua1m9gwDA759wM3OuWDoMbcALwCpwGPOua3j2gOPnQyAnTu/EQqAhxUAIhI3zLnY724vLy93GzZs8LqM0ygARCSWmdkbzrnyke6jFussKQBEJBGo1ToLAwHwfxQAIhL31HKN0dsBcA95eTcoAEQkrqn1GoN3B0BZ2VoFgIjENbVgo6QAEJFEpJPKjEJf3xG2bfsCbW1PKwBEJKEoBM7g6NEtbN36F3R3N1Bc/I8UFX1NASAiCUMhMIJ9+56kvv5GUlOnsmxZFdnZlV6XJCISVgqBIQSDJ2hsvJW9ex9h2rQPsGTJT8nIyPe6LBGRsFMIvEt393a2bv04R4/+kaKi1cybdw8pKXqbRCQxqXUbpK3t36mruw4z49xz/4Pc3D/3uiQRkYhSCAD9/b3s2HEHu3d/h8mTV3DOOT9jwoRir8sSEYm4pA+Bnp5Wamqupqvr98yefROlpf9ESkqG12WJiERFUodAR0cVNTWfIhg8zuLFP2HWrE97XZKISFQl5YR35/ppbv4GGzdeTnr6DFasWK8AEJGklHRHAoHAQerqrqG9/dfMnPkZysoeJjV1ktdliYh4IqlCoKvrdWpqPkEgsJ+FC/+Z/PxVmJnXZYmIeCYpQsA5R2vr99m+/W/JyCjkggteY8qUFV6XJSLiuYQPgddeW8eePX9Nbu4Wpk//MIsW/Yj09GyvyxIRiQkJPTD82mu/YMeOK8jO3sK//EsaR458TQEgIjJIQh8JvPzyFsBx332wdatjyZLfcfHFF3tdlohIzEjoEPjABy5n5cp7CQQC+Hw+KisrvS5JRCSmJHQIVFRUUFVVRXV1NZWVlVRUVHhdkohITEnoEICBIFDjLyIytIQeGBYRkZEpBEREkphCQEQkiSkERESSmEJARCSJKQRERJKYOee8ruGMzKwN2Bmhp88FDkbouaNN+xKbtC+xKRn2Za5zbsZID4yLEIgkM9vgnCv3uo5w0L7EJu1LbNK+DFB3kIhIElMIiIgkMYUArPW6gDDSvsQm7Uts0r6gMQERkaSmIwERkSSmEBARSWJJFwJm9nEz22pm/WY27JQqM2s2s81m9paZbYhmjaM1hn35oJltM7NGM1sdzRpHy8xyzOwlM2sI/RzyPKBmFgx9Jm+Z2XPRrnMkZ3qfzSzDzJ4O3f7fZjYv+lWOzij25Tozaxv0WXzeizrPxMweM7MDZrZlmNvNzL4X2s9NZnZBtGscrVHsS6WZdQ36TO4a1RM755LqH7AYKAOqgfIR7tcM5Hpd73j3BUgFtgMlgA/YCCzxuvYh6rwPWB26vBr41jD3O+p1rWf7PgM3Af8cunw18LTXdY9jX64DHvS61lHsy/uBC4Atw9z+IeBXgAHvBf7b65rHsS+VwH+O9XmT7kjAOVfrnNvmdR3hMMp9uQhodM41OecCwFPAVZGvbsyuAh4PXX4c+IiHtZyN0bzPg/fx58BKM7Mo1jha8fJ/5oyccy8D7SPc5SrgCTfgdSDLzPKjU93YjGJfzkrShcAYOOBFM3vDzFZ5Xcw4FAC7B11vCW2LNbOcc3tDl/cBs4a5X6aZbTCz180sloJiNO/zqfs45/qALmB6VKobm9H+n/lfoS6Un5vZnOiUFnbx8vsxWhVmttHMfmVm54zmAQl5ekkzWwfkDXHTnc65Z0f5NJc451rNbCbwkpnVhZI4qsK0LzFhpH0ZfMU558xsuLnLc0OfSwnwGzPb7JzbHu5a5Yz+A/ipc67HzG5k4AjnUo9rSnZvMvD7cdTMPgT8O7DgTA9KyBBwzl0WhudoDf08YGa/ZOAQOeohEIZ9aQUG/5VWGNoWdSPti5ntN7N859ze0OH4gWGe4+Tn0mRm1cByBvqvvTaa9/nkfVrMLA2YBhyKTnljcsZ9cc4NrvtRBsZ04lHM/H6Ml3Pu8KDLz5vZD80s1zk34iJ56g4agplNMrMpJy8DVwBDjsjHgfXAAjMrNjMfAwOSMTWrJuQ54NrQ5WuB045yzCzbzDJCl3OB9wE1UatwZKN5nwfv418Av3GhEb0Yc8Z9eVe/+YeB2ijWF07PAZ8LzRJ6L9A1qFsyrphZ3skxJjO7iIH2/cx/ZHg94u3BCPtHGej36wH2A3yryqYAAADESURBVC+Ets8Gng9dLmFgRsRGYCsDXS+e1342+xK6/iGgnoG/mGN1X6YDVUADsA7ICW0vBx4NXb4Y2Bz6XDYDN3hd97v24bT3GfgH4MOhy5nAz4BG4A9Aidc1j2Nf1oR+NzYCvwUWeV3zMPvxU2Av0Bv6XbkB+CLwxdDtBvwgtJ+bGWHGoNf/RrEvtwz6TF4HLh7N82rZCBGRJKbuIBGRJKYQEBFJYgoBEZEkphAQEUliCgERkSSmEBARSWIKARGRJPb/ARf++QsyY6zDAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有多项式的Ridge 回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RidgeRegression(Regression):\n",
    "    \"\"\"带有多项式和归一化的Ridge回归\n",
    "    -----------------------------\n",
    "    degree:最大阶数\n",
    "    alpha:正则化系数\n",
    "    n_iterations:步数\n",
    "    learning_rate:步长\n",
    "    normalized\n",
    "    \"\"\"\n",
    "    def __init__(self,degree,alpha,n_iterations=3000,learning_rate=0.01,normailzed=True):\n",
    "        self.degree=degree\n",
    "        self.regularization=l2_regularization(alpha=alpha)\n",
    "        self.normalized=normailzed\n",
    "        super(RidgeRegression,self).__init__(n_iterations,learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        super(RidgeRegression, self).fit(X,y)\n",
    "    \n",
    "    def predict(self,X):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        return super(RidgeRegression,self).predict(X)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 238,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=RidgeRegression(degree=5,alpha=100,n_iterations=1000,learning_rate=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(80, 6)\n"
     ]
    }
   ],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20, 6)\n",
      "方差: 350.5175685249791\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有多项式的ElasticNet 回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ElasticNetRegression(Regression):\n",
    "    \"\"\"\n",
    "    带有L1L2调和的线性回归\n",
    "    \n",
    "    -----------------\n",
    "    degree\n",
    "    alpha\n",
    "    l1_ratio\n",
    "    n_iterations\n",
    "    learning_rate\n",
    "    normalized\n",
    "    \"\"\"\n",
    "    def __init__(self,degree,alpha=0.5,l1_ratio=0.5,n_iterations=3000,learning_rate=0.01,normalized=True):\n",
    "        self.degree=degree\n",
    "        self.regularization=l1_l2_regularization(alpha=alpha,l1_ratio=l1_ratio)\n",
    "        self.normalized=normalized\n",
    "        super(ElasticNetRegression,self).__init__(n_iterations,learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        super(ElasticNetRegression,self).fit(X,y)\n",
    "    \n",
    "    def predict(self,X):\n",
    "        X=polynomial_features(X,degree=self.degree)\n",
    "        if self.normalized:\n",
    "            X=normalize(X)\n",
    "        return super(ElasticNetRegression,self).predict(X)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=ElasticNetRegression(degree=3,alpha=2000,l1_ratio=0.8,n_iterations=1000,learning_rate=0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(80, 4)\n"
     ]
    }
   ],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20, 4)\n",
      "方差: 405.6138475958538\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读入真实的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "train=pd.read_csv('datas/house_data.csv')\n",
    "y=np.asarray(train['SalePrice'])\n",
    "train1=train.drop(['Id','SalePrice'],axis=1)\n",
    "X=np.asarray(pd.get_dummies(train1).reset_index(drop=True))\n",
    "X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=123)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=ElasticNetRegression(degree=1,alpha=1000, l1_ratio=0.5, n_iterations=80000,learning_rate=0.001)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 257,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1168, 304)\n"
     ]
    }
   ],
   "source": [
    "model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 258,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(292, 304)\n"
     ]
    }
   ],
   "source": [
    "pred=model.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 259,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 预测立群点，失败的数据\n",
    "logrmse=np.sqrt(mean_squared_error(np.log(abs(y_test)),np.log(abs(pred))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 260,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.3455434843861849"
      ]
     },
     "execution_count": 260,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "n=len(model.training_errors)\n",
    "training=plt.plot(range(n), model.training_errors, label=\"Training Error\")\n",
    "#plt.legend(handles=[training])\n",
    "plt.title(\"Error Plot\")\n",
    "plt.ylabel('MSE')\n",
    "plt.xlabel('Iterations')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据RobustScaler归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import RobustScaler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 266,
   "metadata": {},
   "outputs": [],
   "source": [
    "def benchmark(model,testset, label):\n",
    "    pred=model.predict(testset)\n",
    "    #print(pred)\n",
    "    if pred[pred<0].shape[0]>0:\n",
    "        print(\"Neg Value\")\n",
    "        return -1\n",
    "    rmse=np.sqrt(mean_squared_error(label,pred))\n",
    "    lrmse=np.sqrt(mean_squared_error(np.log(label),np.log(abs(pred))))\n",
    "    print(\"RMSE:\",rmse)\n",
    "    print(\"LRMSE:\",lrmse)\n",
    "    return lrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 267,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_test():\n",
    "    model=make_pipeline(RobustScaler(), ElasticNetRegression(degree=1,alpha=1000,l1_ratio=0.5,n_iterations=80000,learning_rate=0.001))\n",
    "    model.fit(X_train,y_train)\n",
    "    lrmse=benchmark(model, X_test, y_test)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 268,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1168, 304)\n",
      "(292, 304)\n",
      "RMSE: 51120.0079643827\n",
      "LRMSE: 0.2421903404751488\n"
     ]
    }
   ],
   "source": [
    "train_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br><br>\n",
    "## 普通多项式回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 269,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from random import choice  \n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 289,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def create_points():\n",
    "    n=5\n",
    "    x = np.linspace(0,9, n)\n",
    "    y2 = x*x - 10*x+2 + np.random.randn(n) #构造数据\n",
    "    return x,y2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 290,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def create_test():\n",
    "    n=150\n",
    "    xtest = np.linspace(0,9,n)\n",
    "    ytest = xtest*xtest - 10*xtest + 2 + np.random.randn(n)# x^2 + x +2 \n",
    "    return xtest,ytest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 291,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def ploy_info():\n",
    "    poly1 = PolynomialFeatures(1)\n",
    "    poly2 = PolynomialFeatures(2)\n",
    "    polym = PolynomialFeatures(7)\n",
    "    return poly1,poly2,polym"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 292,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# [x1,x2] -> [1,x1,x2,x1^2,x1*x2,x2^2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 293,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "xtrain,ytrain=create_points()\n",
    "xtest,ytest = create_test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 294,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "poly1,poly2,polym = ploy_info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 295,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "## 一阶\n",
    "xtrain_ploy1 = poly1.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "linemodel_ploy1 = LinearRegression()\n",
    "\n",
    "linemodel_ploy1.fit(xtrain_ploy1,ytrain) # train\n",
    "\n",
    "ploy1_pred = linemodel_ploy1.predict(poly1.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 279,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 二阶\n",
    "xtrain_ploy2 = poly2.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "linemodel_ploy2 = LinearRegression()\n",
    "\n",
    "linemodel_ploy2.fit(xtrain_ploy2,ytrain)\n",
    "\n",
    "ploy2_pred = linemodel_ploy2.predict(poly2.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 280,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 多阶\n",
    "xtrain_polym = polym.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "linemodel_polym = LinearRegression()\n",
    "\n",
    "linemodel_polym.fit(xtrain_polym,ytrain)\n",
    "\n",
    "polym_pred = linemodel_polym.predict(polym.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 281,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt0,  = plt.plot(xtrain,ytrain,'ko',label=\"true value\")\n",
    "plt1,  = plt.plot(xtest,ploy1_pred,'r',label=\"D1\")\n",
    "plt2,  = plt.plot(xtest,ploy2_pred,'b',label=\"D2\")\n",
    "plt3,  = plt.plot(xtest,polym_pred,'g',label=\"D8\")\n",
    "\n",
    "\n",
    "plt.legend(handles=[plt0, plt1, plt2, plt3])\n",
    "plt.axis([0, 10, -80, 40])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则化效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 282,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "alpha=500\n",
    "max_iter=40000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 283,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Ridge\n",
    "xtrain_polym = polym.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "Ridge_polym = Ridge(alpha=alpha,max_iter=max_iter)\n",
    "\n",
    "Ridge_polym.fit(xtrain_polym,ytrain)\n",
    "\n",
    "Ridge_pred = Ridge_polym.predict(polym.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 284,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# LASSO\n",
    "xtrain_polym = polym.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "Lasso_polym = Lasso(alpha=alpha,max_iter=max_iter)\n",
    "\n",
    "Lasso_polym.fit(xtrain_polym,ytrain)\n",
    "\n",
    "Lasso_pred = Lasso_polym.predict(polym.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 285,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# ElasticNet\n",
    "xtrain_polym = polym.fit_transform(xtrain.reshape(-1,1))\n",
    "\n",
    "ElasticNet_polym = ElasticNet(alpha=alpha,max_iter=max_iter,l1_ratio=0.2)\n",
    "\n",
    "ElasticNet_polym.fit(xtrain_polym,ytrain)\n",
    "\n",
    "ElasticNet_pred = ElasticNet_polym.predict(polym.transform(xtest.reshape(-1,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 286,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt0,  = plt.plot(xtest,ploy2_pred,'k--',label=\"true value\")\n",
    "plt1,  = plt.plot(xtest,Ridge_pred,'r',label=\"Ridge_pred\")\n",
    "plt2,  = plt.plot(xtest,Lasso_pred,'b',label=\"Lasso_pred\")\n",
    "plt3,  = plt.plot(xtest,ElasticNet_pred,'y',label=\"ElasticNet_pred\")\n",
    "plt4,  = plt.plot(xtest,polym_pred,'g',label=\"D8\")\n",
    "\n",
    "plt.legend(handles=[plt0, plt1, plt2, plt3, plt4])\n",
    "plt.axis([0, 10, -40, 20])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 288,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[0;31mInit signature:\u001b[0m \u001b[0mLinearRegression\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfit_intercept\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnormalize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy_X\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_jobs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
       "\u001b[0;31mDocstring:\u001b[0m     \n",
       "Ordinary least squares Linear Regression.\n",
       "\n",
       "Parameters\n",
       "----------\n",
       "fit_intercept : boolean, optional, default True\n",
       "    whether to calculate the intercept for this model. If set\n",
       "    to False, no intercept will be used in calculations\n",
       "    (e.g. data is expected to be already centered).\n",
       "\n",
       "normalize : boolean, optional, default False\n",
       "    This parameter is ignored when ``fit_intercept`` is set to False.\n",
       "    If True, the regressors X will be normalized before regression by\n",
       "    subtracting the mean and dividing by the l2-norm.\n",
       "    If you wish to standardize, please use\n",
       "    :class:`sklearn.preprocessing.StandardScaler` before calling ``fit`` on\n",
       "    an estimator with ``normalize=False``.\n",
       "\n",
       "copy_X : boolean, optional, default True\n",
       "    If True, X will be copied; else, it may be overwritten.\n",
       "\n",
       "n_jobs : int or None, optional (default=None)\n",
       "    The number of jobs to use for the computation. This will only provide\n",
       "    speedup for n_targets > 1 and sufficient large problems.\n",
       "    ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.\n",
       "    ``-1`` means using all processors. See :term:`Glossary <n_jobs>`\n",
       "    for more details.\n",
       "\n",
       "Attributes\n",
       "----------\n",
       "coef_ : array, shape (n_features, ) or (n_targets, n_features)\n",
       "    Estimated coefficients for the linear regression problem.\n",
       "    If multiple targets are passed during the fit (y 2D), this\n",
       "    is a 2D array of shape (n_targets, n_features), while if only\n",
       "    one target is passed, this is a 1D array of length n_features.\n",
       "\n",
       "intercept_ : array\n",
       "    Independent term in the linear model.\n",
       "\n",
       "Examples\n",
       "--------\n",
       ">>> import numpy as np\n",
       ">>> from sklearn.linear_model import LinearRegression\n",
       ">>> X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])\n",
       ">>> # y = 1 * x_0 + 2 * x_1 + 3\n",
       ">>> y = np.dot(X, np.array([1, 2])) + 3\n",
       ">>> reg = LinearRegression().fit(X, y)\n",
       ">>> reg.score(X, y)\n",
       "1.0\n",
       ">>> reg.coef_\n",
       "array([1., 2.])\n",
       ">>> reg.intercept_ # doctest: +ELLIPSIS\n",
       "3.0000...\n",
       ">>> reg.predict(np.array([[3, 5]]))\n",
       "array([16.])\n",
       "\n",
       "Notes\n",
       "-----\n",
       "From the implementation point of view, this is just plain Ordinary\n",
       "Least Squares (scipy.linalg.lstsq) wrapped as a predictor object.\n",
       "\u001b[0;31mFile:\u001b[0m           ~/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/sklearn/linear_model/base.py\n",
       "\u001b[0;31mType:\u001b[0m           ABCMeta\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "LinearRegression?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4rc1"
  },
  "toc-autonumbering": false
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
